package com.cidetec.controlador;

import com.cidetec.business.AdminLibroBusiness;
import com.cidetec.business.AdminSubirArchivoBusiness;
import com.cidetec.modelo.entidad.Persona;
import com.cidetec.modelo.entidad.Libro;
import com.cidetec.modelo.entidad.LibroReferencia;
import com.cidetec.modelo.entidad.LibroUbicacion;
import com.cidetec.utils.Constantes;
import com.cidetec.utils.LazySorterLibro;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ManagedBean(name = "adminLibroController")
@ViewScoped
public class AdminLibroController {

    private final static Logger logger = LoggerFactory.getLogger(AdminLibroController.class);

    @ManagedProperty("#{AdminLibroBusiness}")
    private transient AdminLibroBusiness adminBusiness;

    List<Libro> listLibros;
    Libro selectedLibro;

    private LazyDataModel<Libro> lazyDataModel;

    public AdminLibroController() {
    }

    public void onRowSelect(SelectEvent event) {
        selectedLibro = ((Libro) event.getObject());
    }

    public void consultarLibroExecute() {
        listLibros = adminBusiness.consultarLibro();
        LibroUbicacion libroUbicacion = listLibros.get(0).getLibroUbicacion();
        System.out.println(libroUbicacion.getUbicacion());
        lazyDataModel = new LazyDataModel<Libro>() {
            List<Libro> datasource = listLibros;

            @Override
            public Libro getRowData(String rowKey) {
                for (Libro libro : datasource) {
                    if (libro.getCodigoBarras().equals(rowKey)) {
                        return libro;
                    }
                }
                return null;
            }

            @Override
            public List<Libro> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                List<Libro> data = new ArrayList<>();

                //filter  
                for (Libro libro : datasource) {
                    boolean match = true;
                    for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                        try {
                            String filterProperty = it.next();
                            Field field;
                            String filterValue = "";
                            String fieldValue;
                            if (filterProperty.contains("libroReferencia")) {
                                filterValue = filters.get(filterProperty);
                                filterProperty = filterProperty.replace("libroReferencia.", "");
                                LibroReferencia libroReferencia = libro.getLibroReferencia();
                                field = libroReferencia.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(libroReferencia));
                            } else if (filterProperty.contains("libroUbicacion.")) {
                                filterValue = filters.get(filterProperty);
                                filterProperty = filterProperty.replace("libroUbicacion.", "");
                                LibroUbicacion libroUbicacion = libro.getLibroUbicacion();
                                field = libroUbicacion.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                fieldValue = String.valueOf(field.get(libroUbicacion));
                            } else {
                                field = libro.getClass().getDeclaredField(filterProperty);
                                field.setAccessible(true);
                                filterValue = filters.get(filterProperty);
                                fieldValue = String.valueOf(field.get(libro));
                            }
                            if (filterValue == null || fieldValue.contains(filterValue)) {
                                match = true;
                            } else {
                                match = false;
                                break;
                            }
                        } catch (Exception e) {
                            match = false;
                        }
                    }

                    if (match) {
                        data.add(libro);
                    }
                }

//                sort  
                if (sortField != null) {
                    Collections.sort(data, new LazySorterLibro(sortField, sortOrder));
                }
                if (sortField == null) {
                    sortField = "defaultSortField";
                }
                //rowCount  
                int dataSize = data.size();
                this.setRowCount(dataSize);

                //paginate  
                if (dataSize > pageSize) {
                    try {
                        return data.subList(first, first + pageSize);
                    } catch (IndexOutOfBoundsException e) {
                        return data.subList(first, first + (dataSize % pageSize));
                    }
                } else {
                    return data;
                }
            }

            @Override
            public Object getRowKey(Libro t) {
                return t.getCodigoBarras();
            }
        };
    }

    public void eliminarLibroExecute() {
        adminBusiness.eliminarLibro(selectedLibro);
        switch (adminBusiness.getCodigo()) {
            case Constantes.CODIGO_BIEN:
                System.out.println("consultarLibro");
                FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_INFO, "IPN-CIDETEC Mensaje", "¡Bien!"));
                break;
            case Constantes.CODIGO_ERROR:
                FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "IPN-CIDETEC Mensaje", "¡Error!"));
                break;
        }
    }

    public void modificarLibroExecute() {
        adminBusiness.modificarLibro(selectedLibro);
        switch (adminBusiness.getCodigo()) {
            case Constantes.CODIGO_BIEN:
                System.out.println("consultarLibro");
                FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_INFO, "IPN-CIDETEC Mensaje", "¡Bien!"));
                break;
            case Constantes.CODIGO_ERROR:
                FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "IPN-CIDETEC Mensaje", "¡Error!"));
                break;
        }

    }

    public void setAdminBusiness(AdminLibroBusiness adminBusiness) {
        this.adminBusiness = adminBusiness;
    }

    public List<Libro> getListLibros() {
        consultarLibroExecute();
        return listLibros;
    }

    public void setListLibros(List<Libro> listLibros) {
        this.listLibros = listLibros;
    }

    public Libro getSelectedLibro() {
        return selectedLibro;
    }

    public void setSelectedLibro(Libro selectedLibro) {
        this.selectedLibro = selectedLibro;
    }

    public LazyDataModel<Libro> getLazyDataModel() {
        return lazyDataModel;
    }

    public void setLazyDataModel(LazyDataModel<Libro> lazyDataModel) {
        this.lazyDataModel = lazyDataModel;
    }

}
